package cn.edu.usst.cs.ori;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class PiSegmentCalculator {

    // 设置精度，取决于所需的位数。MathContext 控制运算精度。
    private static final MathContext MATH_CONTEXT = new MathContext(20, RoundingMode.HALF_UP);

    public static String calculatePiSegment(int start, int length) {
        StringBuilder piSegment = new StringBuilder();

        for (int i = start; i < start + length; i++) {
            piSegment.append(computePiDigit(i));
        }

        return piSegment.toString();
    }

    private static int computePiDigit(int position) {
        // 计算第 position 位的 pi 值
        BigDecimal sum = BigDecimal.ZERO;
        for (int k = 0; k <= position; k++) {
            BigDecimal currentTerm = calculateBBPTerm(k, position);
            sum = sum.add(currentTerm, MATH_CONTEXT);
        }

        // 提取小数部分的数字
        BigDecimal fractionalPart = sum.remainder(BigDecimal.ONE);
        fractionalPart = fractionalPart.multiply(BigDecimal.TEN, MATH_CONTEXT);
        return fractionalPart.intValue();
    }

    private static BigDecimal calculateBBPTerm(int k, int position) {
        BigDecimal base = BigDecimal.valueOf(16).pow(position - k, MATH_CONTEXT);
        BigDecimal term = BigDecimal.valueOf(4).divide(BigDecimal.valueOf(8 * k + 1), MATH_CONTEXT)
                .subtract(BigDecimal.valueOf(2).divide(BigDecimal.valueOf(8 * k + 4), MATH_CONTEXT))
                .subtract(BigDecimal.valueOf(1).divide(BigDecimal.valueOf(8 * k + 5), MATH_CONTEXT))
                .subtract(BigDecimal.valueOf(1).divide(BigDecimal.valueOf(8 * k + 6), MATH_CONTEXT));

        return term.divide(base, MATH_CONTEXT);
    }
}
